#include "StdAfx.h"
#include "ConsoleFrame.h"

ConsoleFrame::ConsoleFrame(unsigned int width, unsigned int height)
{
	_Width = width;
	_Height = height;
	_Order = None;
	*_TextBuffer = 0;
	_Left = 0;
	_Top = 0;
}

ConsoleFrame::~ConsoleFrame(void)
{
}

void ConsoleFrame::AddFrame(shared_ptr<ConsoleFrame> frame, SplitOrder order)
{
	CHECKARGV(frame.get() != NULL);
	CHECKARGV(*_TextBuffer == 0);
	CHECKARGV(_Order == None || order == _Order);

	if (_Order == None)
		_Order = order;

	_List.push_back(frame);
	CalculateSizeForSiblings(_Left, _Top, _Width, _Height);
}

HRESULT ConsoleFrame::SetTextBuffer(char * text)
{
	CHECKARG(text != NULL);
	CHECKARG(_List.size() == 0);
	CHECKARG(_Order == None);

	strcpy_s(_TextBuffer, 10000, text);
	return S_OK;
}

void ConsoleFrame::SetSize(unsigned int left,
	unsigned int top,
	unsigned int width,
	unsigned int height)
{
	_Width = width;
	_Height = height;
	_Left = left;
	_Top = top;
	CalculateSizeForSiblings(_Left, _Top, width, height);
}

void ConsoleFrame::CalculateSizeForSiblings(
	unsigned int newleft,
	unsigned int newtop,
	unsigned int newwidth,
	unsigned int newheight)
{
	_Left = newleft;
	_Top = newtop;
	_Width = newwidth;
	_Height = newheight;

	if (_List.size() == 0)
		return;
	CHECKARGV(_Order == Horizontal || _Order == Vertical);

	unsigned int size;
	if (_Order == Horizontal)
		size = newwidth;
	else
		size = newheight;

	unsigned int count = _List.size();
	unsigned int wsize = size / count;
	unsigned int last = size;
	unsigned int start = 0;
	if (_Order == Horizontal)
		start = _Left;
	else
		start = _Top;
	for (unsigned int i = 0; i < count; i++)
	{
		if (i == count-1)
			wsize = last;
		if (_Order == Horizontal)
			_List[i]->CalculateSizeForSiblings(start, newtop, wsize, newheight);
		else
			_List[i]->CalculateSizeForSiblings(newleft, start ,newwidth, wsize);
		last -= wsize;
		start += wsize;
	}
	ASSERT(last == 0);
}

void ConsoleFrame::PrintTextBuffer(void) const
{
	SetCursor(_Left, _Top);
	printf("\061");
	SetCursor(_Left+_Width, _Top+_Height);
	printf("#");
}

HRESULT ConsoleFrame::ShowContent(void)
{
	if (_List.size() == 0)
	{
		if (*_TextBuffer  != 0)
		{
			PrintTextBuffer();
		}
	}
	else
	{
		for (FrameList::iterator it = _List.begin(); it != _List.end(); it++)
		{
			shared_ptr<ConsoleFrame> cf = *it;
			cf->ShowContent();
		}
	}

	return S_OK;
}

void ConsoleFrame::SetCursor(short x, short y)
{
	HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
	COORD position = { x, y }; 
	SetConsoleCursorPosition( hStdout, position );
}
